home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 February: Tool Chest / Dev.CD Feb 94.toast / New System Software Extensions / QuickDraw™ GX v1.0ß2 / Sample Code / Printing Samples / Printer Drivers… / ImageWriter / OldApp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-13  |  14.9 KB  |  536 lines  |  [TEXT/MPS ]

  1. /*
  2.     copyright © 1992 Apple Computer Inc.  All rights reserved.
  3.     Apple Confidential - Do Not Distribute
  4.     
  5.     OldApp.c
  6.     This file implements old application message overrides for the specific driver.
  7.     
  8.     Included in this file is the old PrintRecord emulation.  Note that the ImageWriter
  9.     PrintRecord is a wonder of misdirection and special cases.  You'll have fun
  10.     figuring out the code - so unless you really want to exactly emulate the ImageWriter
  11.     pages, you shouldn't spend too much time looking at this code.
  12.     
  13.     Modification history
  14.     9/12/93            dmh                Updated for the b2 seed.
  15.     7/23/92            TED                New file today
  16.     
  17. */
  18.  
  19. #include <PrintingDrivers.h>                // Standard printing includes
  20.  
  21. #include "CommonDefines.h"            // things common to .r and .h files
  22.  
  23. /* ----------------------------------------------------------------------------    */
  24. /* INTERNAL TYPEDEFS AND STRUCTURES                                                */
  25. /* ----------------------------------------------------------------------------    */
  26. // ImageWriter wDev values
  27. #define kBest            0x01
  28. #define kPortrait        0x02
  29. #define kTallAdjusted    0x04
  30. #define k50Percent        0x08
  31. #define kNoGaps            0x10
  32. #define kSetResCalled    0x20
  33.  
  34. // some ImageWriter constants
  35. #define kGapSize        60        // gap at top of page in 120ths of an inch
  36. #define kSmallPlaten    16        // platen width in half inches for small IW
  37. #define kBigPlaten        27        // platen width in half inches for the 15" IW
  38.  
  39. /* ----------------------------------------------------------------------------    */
  40. /* FORWARD DECLARES                                                                */
  41. /* ----------------------------------------------------------------------------    */
  42. OSErr SD_ConvertPrintRecordTo(THPrint hoPrint);
  43. OSErr SD_ConvertPrintRecordFrom(gxUniversalPrintRecordHdl huPrint);
  44.  
  45.  
  46. /* ----------------------------------------------------------------------------    */
  47. /* INTERNAL ROUTINES                                                            */
  48. /* ----------------------------------------------------------------------------    */
  49. OSErr    UpdatePrintRecord(THPrint hPrint)
  50. {
  51.     OSErr                        anErr;
  52.     gxUniversalPrintRecordHdl    huPrint = hPrint;
  53.     gxUniversalPrintRecordPtr    puPrint;
  54.     short                        devVRes, devHRes, appVRes, appHRes;
  55.     short                        cPlaten;
  56.     
  57.     // convert to universal format
  58.     anErr = SD_ConvertPrintRecordTo(hPrint);
  59.     if (anErr == noErr)
  60.         {
  61.         // determine application & device resolutions, based upon quality mode, tall adjusted
  62.         // setting, and if the app called SetRsl:
  63.         //    draft - 80(h)*72(v)
  64.         //    faster - 80(h)*72(v)
  65.         //    best - 160(h)*144(v)
  66.         //
  67.         //    draft (tall adjusted) - 72*72
  68.         //    faster (tall adjusted) - 72*72
  69.         //    best (tall adjusted) - 144*144
  70.         
  71.         puPrint = *huPrint;
  72.         if (puPrint->options & gxPreciseBitmap)
  73.             switch(puPrint->qualityMode)
  74.                 {
  75.                 case gxDraftQuality:
  76.                 case gxFasterQuality:
  77.                     devVRes = devHRes = 72;
  78.                     appVRes = appHRes = 72;
  79.                     break;
  80.                     
  81.                 case gxBestQuality:
  82.                     devVRes = devHRes = 144;
  83.                     appVRes = appHRes = 72;
  84.                     break;
  85.                 }
  86.         else
  87.             switch(puPrint->qualityMode)
  88.                 {
  89.                 case gxDraftQuality:
  90.                 case gxFasterQuality:
  91.                     appVRes = devVRes = 72;
  92.                     appHRes = devHRes = 80;
  93.                     break;
  94.                     
  95.                 case gxBestQuality:
  96.                     devVRes = 144;
  97.                     devHRes = 160;
  98.                     appVRes = 72;
  99.                     appHRes = 80;
  100.                     break;
  101.                 }
  102.             
  103.         // SetRsl was called?  Use the resolution specified by the application
  104.         if (puPrint->appVRes != 72)
  105.             {
  106.             appVRes = devVRes = puPrint->appVRes;
  107.             appHRes = devHRes = puPrint->appHRes;
  108.             }
  109.             
  110.         // finally, store the app & device resolutions
  111.         puPrint->devVRes = devVRes;
  112.         puPrint->devHRes = devHRes;
  113.         puPrint->appVRes = appVRes;
  114.         puPrint->appHRes = appHRes;
  115.         
  116.         // here we do page size calculations
  117.         // Please note that this code is confusing - it's purpose is to emulate
  118.         // the existing ImageWriter driver's page size.  Most drivers would not
  119.         // do this - the existing in the system probably is good enough.
  120.         {
  121.         long        pageGap;                // gap at top of page
  122.         long        dvPaper, dhPaper;        // paper size at device res
  123.         long        dvPage, dhPage;            // page size at device res
  124.         long        scanLines, scanBits;    // # of scan lines or bits on page
  125.         long        maxH;                    // maximum width
  126.         long        hOff, vOff;                // margins (horiz & vert) to get paper rect from page rect
  127.         
  128.         // gap at the top of the page in pixels
  129.         pageGap = (kGapSize * appVRes) / 120;
  130.         if (puPrint->options & gxBiggerPages)
  131.             pageGap = 0;
  132.             
  133.         // figure out paper size in application space pixels
  134.         dvPaper = (puPrint->pageV * appVRes) / 120;
  135.         dhPaper = (puPrint->pageH * appHRes) / 120;
  136.                 
  137.         // vertically, align to the head height of 8 pixels
  138.         scanLines = ((dvPaper - pageGap) >> 3) << 3;
  139.         
  140.         // horizontally, allow the biggest width we can handle
  141.         cPlaten = kSmallPlaten;
  142.         if (puPrint->pageH > (9*120) )
  143.             cPlaten = kBigPlaten;
  144.             
  145.         maxH = (cPlaten * appHRes) >> 1;
  146.         if (maxH > dhPaper)
  147.             maxH = dhPaper;
  148.         scanBits = (maxH >> 4) << 4;
  149.         
  150.         if (puPrint->orientation == gxPortraitOrientation)
  151.             {
  152.             // portrait
  153.             
  154.             dhPage = scanBits;
  155.             dvPage = scanLines;
  156.             
  157.             hOff = (dhPage - dhPaper) >> 1;
  158.             vOff = -pageGap;
  159.             }
  160.         else
  161.             {
  162.             // landscape
  163.             
  164.             dhPage = scanLines;
  165.             dvPage = scanBits;
  166.             
  167.             // reverse the paper definition as well
  168.             {
  169.             long iTemp = dhPaper;
  170.             dhPaper = dvPaper;
  171.             dvPaper = iTemp;
  172.             }
  173.             
  174.             hOff = -pageGap;
  175.             vOff = (dvPage - dvPaper) >> 1;
  176.             }
  177.             
  178.         // 50% reduction?  scale everything by 2X
  179.         if (puPrint->options & gxUserFlag0)
  180.             {
  181.             dhPage <<= 1;
  182.             dvPage <<= 1;
  183.             dhPaper <<= 1;
  184.             dvPaper <<= 1;
  185.             hOff <<= 1;
  186.             vOff <<= 1;
  187.             }
  188.             
  189.         // set the page and paper in app space
  190.         puPrint->appPage.left         = puPrint->appPage.top = 0;
  191.         puPrint->appPage.right         = dhPage;
  192.         puPrint->appPage.bottom     = dvPage;
  193.         
  194.         puPrint->appPaper.left         = hOff;
  195.         puPrint->appPaper.top         = vOff;
  196.         puPrint->appPaper.right     = dhPaper + hOff;
  197.         puPrint->appPaper.bottom     = dvPaper + vOff;
  198.                 
  199.         // from page, scale up to device space (in case some weenie decides to look at that)
  200.         puPrint->devPage.left         = puPrint->devPage.top = 0;
  201.         puPrint->devPage.right         = dhPage * devHRes / appHRes;
  202.         puPrint->devPage.bottom     = dvPage * devVRes / appVRes;
  203.         }
  204.         
  205.         // convert back to non-universal format
  206.         anErr = SD_ConvertPrintRecordFrom((gxUniversalPrintRecordHdl) hPrint);
  207.         }
  208.         
  209.     return(anErr);
  210.     
  211. } // UpdatePrintRecord
  212.  
  213. //<FF>
  214. /* ----------------------------------------------------------------------------    */
  215. /* MESSAGE OVERRIDES                                                            */
  216. /* ----------------------------------------------------------------------------    */
  217. OSErr SD_ConvertPrintRecordTo(THPrint hoPrint)
  218. /*
  219.     This call takes a print record in old style (driver specific) format, and
  220.     converts it to the format of "UniversalPrintRecordHdl"
  221. */
  222. {
  223.     TPPrint                        poPrint;            // pointer to old style print record
  224.     gxUniversalPrintRecordHdl    huPrint = hoPrint;    // handle to universal print record
  225.     gxUniversalPrintRecordPtr    puPrint;            // pointer to universal print record
  226.     short                        qualityMode;        // cached quality mode
  227.     short                        wDev;                // cached wDev
  228.     
  229.     // cache pointers for size and speed
  230.     puPrint = *huPrint;
  231.     poPrint = *hoPrint;
  232.     wDev = poPrint->prStl.wDev;
  233.     
  234.     // determine quality mode
  235.     if (poPrint->prJob.bJDocLoop == 0)
  236.         qualityMode = gxDraftQuality;
  237.     else
  238.         {
  239.         if (wDev & kBest)
  240.             qualityMode = gxBestQuality;
  241.         else
  242.             qualityMode = gxFasterQuality;
  243.         }
  244.         
  245.     // universal feed is the inverse of our feed
  246.     puPrint->feed            =    1-(poPrint->prStl.feed);
  247.     
  248.     // wDev 0x02 means portrait, else landscape
  249.     if (wDev & kPortrait) 
  250.         puPrint->orientation    =    gxPortraitOrientation;
  251.     else
  252.         {
  253.         puPrint->orientation    =    gxLandscapeOrientation;
  254.         
  255.         // landscape disabled draft, forces tall adjusted
  256.         if (qualityMode == gxDraftQuality)
  257.             qualityMode = gxFasterQuality;
  258.         wDev |= kTallAdjusted;
  259.         }
  260.         
  261.     // copies are in iCopies field (wow.)
  262.     puPrint->actualCopies        =    poPrint->prJob.iCopies;
  263.     
  264.     // store our flags
  265.     puPrint->options = 0;
  266.     
  267.     // tall adjusted
  268.     if (wDev & kTallAdjusted) 
  269.         puPrint->options |= gxPreciseBitmap;
  270.         
  271.     // 50% reduction
  272.     if (wDev & k50Percent) 
  273.         {
  274.         puPrint->options |= gxUserFlag0;
  275.         puPrint->reduction = 50;
  276.         
  277.         // for 50% reduction, we always return faster to the application
  278.         qualityMode = gxFasterQuality;
  279.         }
  280.     else
  281.         puPrint->reduction = 100;
  282.         
  283.     // no gaps
  284.     if (wDev & kNoGaps) 
  285.         puPrint->options |= gxBiggerPages;
  286.     
  287.     // finally, store quality mode    
  288.     puPrint->qualityMode = qualityMode;
  289.     
  290.     // and we can't have any errors - because this code is too godlike.
  291.     return(noErr);
  292.     
  293. } // SD_ConvertPrintRecordTo
  294.  
  295. //<FF>
  296. /* ----------------------------------------------------------------------------    */
  297. OSErr SD_ConvertPrintRecordFrom(gxUniversalPrintRecordHdl huPrint)
  298. /*
  299.     This call takes a print record in universal format and converts it
  300.     to old style (driver specific) format.
  301.     
  302.     Note: for the ImageWriter, I'm filling in way more things than theoretically
  303.     I need to.  However, since the ImageWriter is one of the oldest print drivers,
  304.     there is much more of a chance that someone assumes something about one or
  305.     more of the fields.
  306. */
  307. {
  308.     gxUniversalPrintRecordPtr    puPrint;            // pointer to universal print record
  309.     THPrint                        hoPrint = huPrint;    // handle to old style print record
  310.     TPPrint                        poPrint;            // pointer to old style print record
  311.     short                        options;            // cached universal options
  312.     short                        qualityMode;        // cached universal quality mode
  313.     short                        actualCopies;        // cached universal copies
  314.     
  315.     // cache pointers for size and speed
  316.     puPrint = *huPrint;
  317.     poPrint = *hoPrint;
  318.  
  319.     // save away fields within the universal record that we'll be stomping over
  320.     // as we convert
  321.     options         = puPrint->options;
  322.     qualityMode     = puPrint->qualityMode;
  323.     actualCopies    = puPrint->actualCopies;
  324.     
  325.     poPrint->iPrVersion            = 4;        // used to be 3, but this is
  326.                                             // a new driver.  We support versions
  327.                                             // 3 and 4
  328.     poPrint->prInfo.iDev        = 0;        // always zero for the ImageWriter
  329.     
  330.     // skip remaining fields in prInfo because they are unchanged
  331.     
  332.     // determine the wDev
  333.     {
  334.     short    wDev;
  335.     
  336.     // this is the wDev value for the ImageWriter
  337.     wDev = 0x0100;
  338.     
  339.     if (puPrint->orientation == gxPortraitOrientation)
  340.         wDev |= kPortrait;
  341.     else
  342.         {
  343.         // for landscape, disable draft and force tall adjusted
  344.         if (qualityMode == gxDraftQuality)
  345.             qualityMode = gxFasterQuality;
  346.             
  347.         options |= gxPreciseBitmap;
  348.         }
  349.     
  350.     // user options
  351.     if (options & gxPreciseBitmap)
  352.         wDev |= kTallAdjusted;
  353.     if (options & gxUserFlag0)
  354.         {
  355.         wDev |= k50Percent;
  356.         qualityMode = gxFasterQuality;
  357.         }
  358.  
  359.     if (options & gxBiggerPages)
  360.         wDev |= kNoGaps;
  361.         
  362.     if (qualityMode == gxBestQuality)
  363.         wDev |= kBest;
  364.         
  365.     // if the application's resolution isn't 72 - then clearly SetRsl must have been called
  366.     // to change it.
  367.     if (poPrint->prInfo.iVRes != 72)
  368.         wDev |= kSetResCalled;
  369.         
  370.     // and finally, save away that short value we worked so hard to determine
  371.     poPrint->prStl.wDev = wDev;
  372.     }
  373.  
  374.     // other fields in prStl remain the same
  375.     
  376.     poPrint->prStl.bPort     = 0;
  377.     poPrint->prStl.feed     = 1 - (puPrint->feed);
  378.     poPrint->prInfoPT.iDev     = (qualityMode == gxBestQuality) ? -768 : 0;
  379.  
  380.     // other fields in prInfoPT remain the same
  381.     {
  382.     Rect    rPage = poPrint->prInfoPT.rPage;
  383.     
  384.     // calculate some fields we don't use - in case someone really wants to look at
  385.     // them for some reason
  386.     poPrint->prXInfo.iRowBytes    = rPage.right >> 3;
  387.     poPrint->prXInfo.iBandV        = 32;
  388.     poPrint->prXInfo.iBandH        = poPrint->prXInfo.iRowBytes << 3;
  389.     poPrint->prXInfo.iDevBytes    = poPrint->prXInfo.iRowBytes * 
  390.                                     poPrint->prXInfo.iBandV + 
  391.                                     poPrint->prXInfo.iBandH;
  392.     poPrint->prXInfo.iBands        = (rPage.bottom+(poPrint->prXInfo.iBandV-1)) / poPrint->prXInfo.iBandV;
  393.     poPrint->prXInfo.bPatScale     = (qualityMode == gxBestQuality) ? -2 : 0;
  394.     poPrint->prXInfo.bUlThick     = 1;
  395.     poPrint->prXInfo.bUlOffset     = 1;
  396.     poPrint->prXInfo.bUlShadow     = 1;
  397.     poPrint->prXInfo.scan        = (poPrint->prStl.wDev | kPortrait) ? 0 : 2;
  398.     poPrint->prXInfo.bXInfoX    = 0;
  399.     }
  400.     
  401.     // other fields in prJob remain the same
  402.     poPrint->prJob.iCopies        = actualCopies;
  403.     poPrint->prJob.bJDocLoop    = (qualityMode == gxDraftQuality) ? 0 : 1;
  404.     
  405.     // this routine is so studly, there can be no errors
  406.     return(noErr);    
  407.     
  408. } // SD_ConvertPrintRecordFrom
  409.  
  410.  
  411. //<FF>
  412. /* ----------------------------------------------------------------------------    */
  413. OSErr SD_PrintRecordToJob(THPrint hPrint, gxJob theJob)
  414. /*
  415.     We convert the "tall adjusted" setting into the correct rendering option for
  416.     the job collection.
  417. */
  418. {
  419.     OSErr    anErr;
  420.     
  421.     anErr = Forward_GXPrintRecordToJob(hPrint, theJob);
  422.     if (anErr == noErr)
  423.         {
  424.         long imagewriterOptions = kSuperRes;
  425.         
  426.         if ((**hPrint).prStl.wDev & kTallAdjusted)
  427.             imagewriterOptions = 0;
  428.             
  429.         anErr = AddCollectionItem(GXGetJobCollection(theJob), 
  430.                     DriverCreator,
  431.                     0,
  432.                     sizeof(imagewriterOptions),
  433.                     &imagewriterOptions);
  434.         }
  435.         
  436.     return(anErr);
  437.     
  438. } // SD_PrintRecordToJob
  439.  
  440. //<FF>
  441. /* ----------------------------------------------------------------------------    */
  442. OSErr SD_PrValidate(    THPrint hPrint,                 // old style print record
  443.                         Boolean *wasChanged)            // was the print record changed?
  444. /*
  445.     This call validates the current print record.  It's fairly simplistic (as were
  446.     all of the old drivers) - the wDev or versions don't match the current, we call
  447.     PrintDefault.  Otherwise, we call UpdatePrintRecord - to allow the driver to sanity
  448.     check any internal fields.
  449.     
  450. */
  451. {
  452.     unsigned short    wDev;                        // note: if this were signed, the shift below would fail                    
  453.     Boolean            recordIsInvalid = true;            
  454.     OSErr            anErr = noErr;
  455.     
  456.     // check the wDev.  The upper byte must be equal to our idea of the wDev
  457.         
  458.     wDev =  (**hPrint).prStl.wDev;    
  459.     wDev >>= 8;                                // get just the device ID
  460.  
  461.     // If the device id is equal, then check the version number of the print record.
  462.     //    Only if that is also equal to the current version, will we return false (valid).
  463.         
  464.     if (     (wDev == 1) 
  465.         &&
  466.             (
  467.             ( ((**hPrint).iPrVersion) == 3 ) ||
  468.             ( ((**hPrint).iPrVersion) == 4 ) 
  469.             )
  470.         )
  471.         recordIsInvalid = false;
  472.             
  473.  
  474.     // If the the print record is not valid, then return the default print record.
  475.     // Otherwise, update the print record, based on the application's calls
  476.     // to PrGeneral.
  477.         
  478.     if (recordIsInvalid)
  479.         PrintDefault(hPrint);
  480.     else
  481.         anErr = UpdatePrintRecord(hPrint);
  482.         
  483.     *wasChanged = recordIsInvalid;
  484.     
  485.     return (anErr);
  486.     
  487. } // SD_PrValidate
  488.  
  489. //<FF>
  490. /* ----------------------------------------------------------------------------    */
  491. OSErr SD_PrJobInit(THPrint hPrint, TPPrDlg * pDlg)
  492. /*
  493.     This routine is called to initialize the job dialog.  We take the default
  494.     behavior - and then disable some of the items based on settings the user
  495.     has made:
  496.         - 50% disables all items
  497.         - apps that call SetRsl disable all items
  498.         - landscape disables draft mode
  499. */
  500. {
  501.     OSErr    anErr;
  502.     
  503.     anErr = Forward_GXPrJobInit(hPrint, pDlg);
  504.     if (anErr == noErr)
  505.         {
  506.         Boolean    disableDraft     = false;
  507.         Boolean    disableAll         = false;
  508.         short    wDev             = (**hPrint).prStl.wDev;
  509.         short    idx;
  510.         Rect    box;
  511.         Handle    item;
  512.         short    type;
  513.         
  514.         if (wDev & k50Percent)
  515.             disableAll = true;
  516.             
  517.         if (wDev & kSetResCalled)
  518.             disableAll = true;
  519.             
  520.         if (!(wDev & kPortrait))
  521.             disableDraft = true;
  522.         
  523.         // disable any controls we need to
  524.         for (idx = 6; idx <= 8; ++idx)
  525.             {
  526.             GetDItem((DialogPtr) *pDlg, idx, &type, &item, &box);
  527.             
  528.             if ( (disableAll) || ((disableDraft) && (idx == 8) ) )
  529.                 HiliteControl((ControlHandle) item, 255);
  530.             
  531.             }
  532.         }
  533.  
  534.     return(anErr);
  535.     
  536. } // SD_PrJobInit